/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * Represents a Community, structured as a linked list of vertices
 */
public class Community {
    
        private CommunityNode _head;
        private CommunityNode _lastNode;
        private int _nodeNum;
        
        /**
         * Gets the first node (representing a vertex) in the linked list
         * @return the first node (representing a vertex) in the linked list
         */
        public CommunityNode getHead()
        {
            return _head;
        }
        
        /**
         * Gets the last node (representing a vertex) in the linked list
         * @return the last node (representing a vertex) in the linked list
         */
        public CommunityNode getLastNode()
        {
            return _lastNode;
        }
                
        /**
         * @return the number of nodes (representing vertices) in the community
         */
        public int getNodeNum()
        {
            return _nodeNum;
        }
        
        /**
         * Constructs an empty community
         */
        public Community()
        {
            _nodeNum = 0;
        }

        /**
         * Constructs a community with one node (representing a vertex)
         * @param head_value 
         */
        public Community(int head_value)
        {
            _head = new CommunityNode(head_value);
            _lastNode = _head;
            _nodeNum = 1;
        }
        
        /**
         * A deep copy constructor
         * @param comm the community object to clone
         */
        public Community(Community comm)
        {
            CommunityNode curr_node;
            this._nodeNum = 0;
            
            if (comm._head != null)
            {
                this._head = new CommunityNode(comm._head);
                this._lastNode = this._head;
                this._nodeNum++;
                
                curr_node = comm._head.next;
                
                while (curr_node != null)
                {
                    this._lastNode.next = new CommunityNode(curr_node);
                    this._lastNode = this._lastNode.next;
                    this._nodeNum++;
                            
                    curr_node = curr_node.next;
                }
            }
            
            assert (this._nodeNum == comm._nodeNum);
        }

        /**
         * Adds a node (representing a vertex) to the community
         * @param value the value of the node (representing a vertex) to add
         */
        public void add(int value)
        {
            if (_lastNode == null)
            {
                    _head = new CommunityNode(value);
                    _lastNode = _head;
                    _nodeNum = 1;
            }
            else
            {
                    _lastNode.next = new CommunityNode(value);
                    _lastNode = _lastNode.next;
                    _nodeNum++;
            }
        }

        /**
         * Merges another community to the this Community object.
         * This is done by appending the linked list to this linked list
         * @param community the community to attach to this Community object
         */
        public void attach(Community community)
        {
                _lastNode.next = community._head;
                _lastNode = community._lastNode;
                _nodeNum += community._nodeNum;
        }
        
        /**
         * Prints out the indices of all the vertices in the community
         */
        public void print()
        {
            CommunityNode curr_node = this._head;
            
            while (curr_node != null)
            {
                //Add 1 so the node indices match those in the text files (node indices start from 0 while those in the file start from 1), when added the nodes in the Graph constructor we subtracted 1 from their index so now we add it back.
                System.out.print((curr_node.value + 1) + " ");
                curr_node = curr_node.next;
            }
        }
}
